package ru.spb.osll.myfit.server.execute;

import ru.spb.osll.myfit.common.TextParsingTools;
import fit.Counts;
import fit.Fixture;
import fit.Parse;
import fitnesse.html.SetupTeardownIncluder;
import fitnesse.wiki.FileSystemPage;
import fitnesse.wiki.PageData;
import fitnesse.wiki.PathParser;
import fitnesse.wiki.WikiPage;
import fitnesse.wiki.WikiPagePath;

public class FitNesseTestRunner {
	protected MyFitFixtureRunner m_fixtureRunner;
	protected MyFitFixtureLoader m_fixtureLoader;
	protected WikiPage m_root;
	
	protected FitNesseTestRunner() {
	}

	public FitNesseTestRunner(String rootPath, String rootDirectoryName,
			MyFitFixtureLoader fixtureLoader, MyFitFixtureRunner fixtureRunner)
			throws Exception {
		m_fixtureLoader = fixtureLoader;
		m_fixtureRunner = fixtureRunner;
		m_root = createRoot(rootPath, rootDirectoryName);
	}
	
	protected WikiPage createRoot(String rootPath, String rootDirectoryName)
			throws Exception {
		return new FileSystemPage(rootPath, rootDirectoryName);
	}
	
	public void run(String pagePath) throws Exception {
		Parse tables = getParse(pagePath);
		Counts counts = new Counts();
		try {
			m_fixtureRunner.doTables(tables);
		} catch (Exception e) {
			exception(m_fixtureRunner, counts, e);
		}

    m_fixtureLoader.close();
	}
	
	private void exception(Fixture fixture, Counts counts, Exception e) {
		counts.exceptions = counts.exceptions + 1;
		Parse tables = new Parse("span", "Exception occurred: ", null, null);
		fixture.exception(tables, e);
		fixture.listener.tableFinished(tables);
		fixture.listener.tablesFinished(counts);
	}
	
	private boolean isTestPage(String pageName) {
		if (pageName.equals(TextParsingTools.SETUP)
				|| pageName.equals(TextParsingTools.TEARDOWN)) {
			return false;
		}
		return true;
	}
	
	protected Parse getParse(String pagePath) throws Exception {
		WikiPagePath path = PathParser.parse(pagePath);
		WikiPage page = m_root.getPageCrawler().getPage(m_root, path);
		PageData pageData = page.getData();
		String pageName = page.getName();
		if (isTestPage(pageName)) {
			pageData.setAttribute("Test", "true");
			SetupTeardownIncluder.includeInto(pageData);
		}
		String html = pageData.getHtml();
		return new Parse(html);
	}
}
